package com.neusoft.elmboot.po;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import com.neusoft.elmboot.constants.EditableProperties;

/**
 * @author chj
 * @date 2024年10月20日
 */
public class VirtualWallet {

	private Long walletId;
	private Long createTime = System.currentTimeMillis();
	private BigDecimal balance = BigDecimal.ZERO;
	private boolean isVIP = true;
	private boolean isAllowedOverdraft = true;
	private BigDecimal overdraftAmount = BigDecimal.ZERO;
	private BigDecimal frozenAmount = BigDecimal.ZERO;

	// 流水
	private List<VirtualWalletTransaction> transactionList;

	// 初始化构造函数
	public VirtualWallet(Long preAllocatedId) {
		this.walletId = preAllocatedId;
	}

	// get ballance
	public BigDecimal balance() {
		return this.balance;
	}

	// get isVIP
	public boolean isVIP() {
		return this.isVIP;
	}

	// get isAllowedOverdraft
	public boolean isAllowedOverdraft() {
		return this.isAllowedOverdraft;
	}

	// get overdraftAmount
	public BigDecimal overdraftAmount() {
		return this.overdraftAmount;
	}

	// get frozenAmount
	public BigDecimal frozenAmount() {
		return this.frozenAmount;
	}

	public List<VirtualWalletTransaction> getTransactionList() {
		return this.transactionList;
	}

	public void setTransactionList(List<VirtualWalletTransaction> transactionList) {
		this.transactionList = transactionList;
	}

	public void frozen(BigDecimal amount) throws InvalidAmountException, InsufficientBalanceException {
		BigDecimal total = getAvailableBalance();
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		if (total.compareTo(amount) < 0) {
			throw new InsufficientBalanceException("余额不足");
		}
		// this.balance.subtract(amount);
		this.frozenAmount = this.frozenAmount.add(amount);
	}

	public void unfrozen(BigDecimal amount) throws InvalidAmountException, InsufficientBalanceException {
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		if (this.frozenAmount.compareTo(amount) < 0) {
			throw new InsufficientBalanceException("frozenAmount不足");
		}
		// this.balance.subtract(amount);
		this.frozenAmount = this.frozenAmount.subtract(amount);
	}

	public void increaseOverdraftAmount(BigDecimal amount) throws Exception {
		if (!isAllowedOverdraft) {
			throw new Exception("notAllowedOverdraft");
		}
		BigDecimal total = this.overdraftAmount.add(amount);
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		if (EditableProperties.OVERDRAFT_MAX_AMOUNT.compareTo(total) < 0) {
			throw new InsufficientBalanceException("超出额度");
		}
		this.overdraftAmount = this.overdraftAmount.add(amount);

	}

	public void decreaseOverdraftAmount(BigDecimal amount) throws Exception {
		if (!isAllowedOverdraft) {
			throw new Exception("notAllowedOverdraft");
		}
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		if (this.overdraftAmount.compareTo(amount) < 0) {
			throw new InsufficientBalanceException("还多了。。");
		}
		this.overdraftAmount = this.overdraftAmount.subtract(amount);
	}

	public void closeOverdraft() throws Exception {
		if (!isAllowedOverdraft) {
			throw new Exception("notAllowedOverdraft");
		}
		if (!(overdraftAmount.compareTo(BigDecimal.ZERO) == 0)) {
			throw new Exception(this.overdraftAmount + "贷款未还清 " + BigDecimal.ZERO);
		}
		this.isAllowedOverdraft = false;

	}

	public void openOverdraft() throws Exception {
		if (!isVIP) {
			throw new Exception("你不是VIP");
		}
		this.isAllowedOverdraft = true;

	}

	public void closeVIP() throws Exception {
		if (!isVIP) {
			throw new Exception("notVIP");
		}
		this.isVIP = false;

	}

	public void openVIP() throws Exception {
		this.isVIP = true;
	}

	public BigDecimal getAvailableBalance() {
		BigDecimal total = this.balance.subtract(frozenAmount);
		if (isAllowedOverdraft) {
			total.add(overdraftAmount);
		}
		return total;
	}

	// debit
	public void debit(BigDecimal amount) throws InsufficientBalanceException, InvalidAmountException {
		BigDecimal total = getAvailableBalance();
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		if (total.compareTo(amount) < 0) {
			throw new InsufficientBalanceException("余额不足");
		}

		this.balance = this.balance.subtract(amount);
	}

	public void credit(BigDecimal amount) throws InvalidAmountException {
		if (amount.compareTo(BigDecimal.ZERO) < 0) {
			throw new InvalidAmountException("负数数量");
		}
		
		this.balance = this.balance.add(amount);
	}

}
